﻿// Learn more about F# at http://fsharp.org
// See the 'F# Tutorial' project for more help.

open System
open System.Data
open System.Data.SqlClient

let GetConnectionString = "MyConnectionString"

let RunDMCWithoutTrans() =
        use user1Connection = new SqlConnection(GetConnectionString)
        user1Connection.Open()

        use user2Connection = new SqlConnection(GetConnectionString)
        user2Connection.Open()

        use user3Connection = new SqlConnection(GetConnectionString)
        user3Connection.Open()

        use sqlcom = new SqlCommand("IF EXISTS " +
                                     "(SELECT * FROM sys.tables WHERE name=N'snapTest') " +
                                     " DROP TABLE snapTest", user1Connection)
        sqlcom.ExecuteNonQuery() |> ignore

        use sqlcom1 = new SqlCommand("CREATE TABLE snapTest ([id] INT IDENTITY, col1 VARCHAR(15))", user1Connection)
        sqlcom1.ExecuteNonQuery() |> ignore

        use sqlcom2 = new SqlCommand("INSERT INTO snapTest VALUES('Niels')", user1Connection)
        sqlcom2.ExecuteNonQuery() |> ignore

        use user3StepZ1 = new SqlCommand("SET TRANSACTION ISOLATION " +
                                          "LEVEL SNAPSHOT " +
                                          "BEGIN TRAN " + "SELECT col1 FROM snapTest WHERE id = 1", user3Connection)
        use user3StepZ1Read = user3StepZ1.ExecuteReader(CommandBehavior.SingleRow)

        use user1Step1 = new SqlCommand("SET TRANSACTION ISOLATION " +
                                         "LEVEL SNAPSHOT " +
                                         "BEGIN TRAN " + "UPDATE snapTest " +
                                         "SET col1 = 'NewNiels' " +
                                         "WHERE id = 1 ", user1Connection)
        user1Step1.ExecuteNonQuery() |> ignore

        use user2Step2 = new SqlCommand("SET TRANSACTION ISOLATION LEVEL SNAPSHOT " +
                                         "BEGIN TRAN " +
                                         "SELECT col1 FROM snapTest " +
                                         "WHERE id = 1", user2Connection) //receives value 'Niels'
        user2Step2.ExecuteNonQuery() |> ignore

        use user1Step3 = new SqlCommand("COMMIT TRAN", user1Connection)
        user1Step3.ExecuteNonQuery() |> ignore

        use user2Step4 = new SqlCommand("SELECT col1 FROM snapTest WHERE id = 1", user1Connection) //receives value 'Niels'
        use user2Step4Read = user2Step4.ExecuteReader(CommandBehavior.SingleRow)

        user2Step4Read.Read() |> ignore
        printfn "%A" user2Step4Read.["col1"]
        user2Step4Read.Close()

        use user2Step5 = new SqlCommand("COMMIT TRAN", user2Connection)
        user2Step5.ExecuteNonQuery() |> ignore

        use user2Step6 = new SqlCommand("SELECT col1 FROM snapTest WHERE id = 1", user2Connection) //receives value 'NewNiels'
        use user2Step6Read = user2Step6.ExecuteReader(CommandBehavior.SingleRow)

        user2Step6Read.Read() |> ignore
        printfn "%A" user2Step6Read.["col1"]
        user2Step6Read.Close()

        user3StepZ1Read.Read() |> ignore
        printfn "%A" user3StepZ1Read.["col1"]
        user3StepZ1Read.Close()

        use user3StepZ2 = new SqlCommand("COMMIT TRAN", user3Connection)
        user3StepZ2.ExecuteNonQuery() |> ignore

        user1Connection.Dispose()
        user2Connection.Dispose()
        user3Connection.Dispose()

[<EntryPoint>]
let main argv = 
    //printfn "%A" argv
    RunDMCWithoutTrans()
    0 // return an integer exit code
